﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//using System;
//using System.Text;
using System.IO;
using System.Security.Cryptography;

namespace Basteroid
{
    class GL_Security
    {
        //默认密钥向量
        public static string m_str_DefaultKey = "tkGGRmBErvc=";
        private static byte[] m_byteArray_DefaultIV = { 0xEF, 0xAB, 0x56, 0x78, 0x90, 0x34, 0xCD, 0x12 };

        /// <summary>
        /// generate private key and public key. arr[0] for private key, arr[1] for public key.
        /// </summary>
        /// <returns></returns>
        public static string[] RSA_GenerateKeys()
        {
            string[] sKeys = new String[2];
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            sKeys[0] = rsa.ToXmlString(true);
            sKeys[1] = rsa.ToXmlString(false);
            return sKeys;
        }

        public static string RSA_GenerateKeyPair()
        {
            string sKey;
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            sKey = rsa.ToXmlString(true);
            return sKey;
        }

        /// <summary>
        /// RSA Encrypt
        /// </summary>
        /// <param name="sSource" >Source string</param>
        /// <param name="sPublicKey" >public key</param>
        /// <returns></returns>
        public static string RSA_EncryptString(string sSource, string sPublicKey)
        {
            Console.WriteLine("Before EncryptString");

            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            string plaintext = sSource;
            rsa.FromXmlString(sPublicKey);
            byte[] cipherbytes;
            byte[] byteEn = rsa.Encrypt(Encoding.Unicode.GetBytes("a"), false);
            cipherbytes = rsa.Encrypt(Encoding.Unicode.GetBytes(plaintext), false);

            StringBuilder sbString = new StringBuilder();
            for (int i = 0; i < cipherbytes.Length; i++)
            {
                sbString.Append(cipherbytes[i] + ",");
            }
            return sbString.ToString();

            //byte[] encyptedBytes = rsa.Encrypt(Encoding.Unicode.GetBytes(plaintext), false);
            //string re = System.Text.Encoding.Unicode.GetString(encyptedBytes);
            //return re.Replace("\0", "");
        }

        /// <summary>
        /// RSA Decrypt
        /// </summary>
        /// <param name="sSource">Source string</param>
        /// <param name="sPrivateKey">Private Key</param>
        /// <returns></returns>
        public static string RSA_DecryptString(string sSource, string sPrivateKey)
        {
            Console.WriteLine("Before DecryptString");

            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(sPrivateKey);
            byte[] byteEn = rsa.Encrypt(Encoding.Unicode.GetBytes("a"), false);
            string[] sBytes = sSource.Split(',');

            for (int j = 0; j < sBytes.Length; j++)
            {
                if (sBytes[j] != "")
                {
                    byteEn[j] = Byte.Parse(sBytes[j]);
                }
            }
            byte[] plaintbytes = rsa.Decrypt(byteEn, false);
            return Encoding.Unicode.GetString(plaintbytes);

            //byte[] bytesToDecrypt = System.Text.Encoding.Unicode.GetBytes(sSource);
            //byte[] plaintbytes = rsa.Decrypt(bytesToDecrypt, false);

            //string re = System.Text.Encoding.Unicode.GetString(plaintbytes);
            //return re.Replace("\0", ""); 
        }

        ///　<summary>
        ///　DES加密字符串
        ///　</summary>
        ///　<param　name="encryptString">待加密的字符串</param>
        ///　<param　name="encryptKey">加密密钥,要求为8位</param>
        ///　<returns>加密成功返回加密后的字符串，失败返回源串</returns>
        public static string DES_Encrypt(string encryptString, string encryptKey)
        {
            try
            {
                byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
                byte[] rgbIV = m_byteArray_DefaultIV;
                byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
                DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Convert.ToBase64String(mStream.ToArray());
            }
            catch
            {
                return encryptString;
            }
        }

        ///　<summary>
        ///　DES解密字符串
        ///　</summary>
        ///　<param　name="decryptString">待解密的字符串</param>
        ///　<param　name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param& gt;
        ///　<returns>解密成功返回解密后的字符串，失败返源串</returns>
        public static string DES_Decrypt(string decryptString, string decryptKey)
        {
            try
            {
                byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey.Substring(0, 8));
                byte[] rgbIV = m_byteArray_DefaultIV;
                byte[] inputByteArray = Convert.FromBase64String(decryptString);
                DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Encoding.UTF8.GetString(mStream.ToArray());
            }
            catch
            {
                return decryptString;
            }
        }

        ///　<summary>
        ///　DES加密字符串
        ///　</summary>
        ///　<param　name="encryptString">待加密的字符串</param>
        ///　<param　name="encryptKey">加密密钥,要求为8位</param>
        ///　<returns>加密成功返回加密后的字符串，失败返回源串</returns>
        public static string DES_Encrypt_ByDefaultKey(string encryptString)
        {
            string encryptKey = m_str_DefaultKey;
            try
            {
                byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
                byte[] rgbIV = m_byteArray_DefaultIV;
                byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
                DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Convert.ToBase64String(mStream.ToArray());
            }
            catch
            {
                return encryptString;
            }
        }

        ///　<summary>
        ///　DES解密字符串
        ///　</summary>
        ///　<param　name="decryptString">待解密的字符串</param>
        ///　<param　name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param& gt;
        ///　<returns>解密成功返回解密后的字符串，失败返源串</returns>
        public static string DES_Decrypt_ByDefaultKey(string decryptString)
        {
            string decryptKey = m_str_DefaultKey;

            try
            {
                byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey.Substring(0, 8));
                byte[] rgbIV = m_byteArray_DefaultIV;
                byte[] inputByteArray = Convert.FromBase64String(decryptString);
                DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Encoding.UTF8.GetString(mStream.ToArray());
            }
            catch
            {
                return decryptString;
            }
        }
    }
}
